<?php
/**
 * Classe responsável pelo gerenciamento do datagrid
 * 
 * @author Cristiano Gomes
 */
class DataGrid{

	private $grid_campos = array();
	private $chave_primaria;
	private $acoes_permitidas = array();
	private $grid_filtros = array();
	private $grid_pagina;
	private $extensao_paginacao = 5;
	private $itens_por_pagina = 20;
	private $ctrl; 
	private $ordenacao;

	/**
	 * @var  Datagrid_FiltroStrategy
	 */
	protected $filtroStrategy;

	/**
	 * @var Datagrid_OrdenacaoStrategy
	 */
	protected $ordenacaoStrategy;
	
	/**
	 * @var Datagrid_ItensControlStrategy
	 */
	protected $itensControlStrategy;
	
	/**
	 * Ajusta os dados do controlador com a classe
	 * @param $ctrl
	 */
	public function AjustaControle(Controle $ctrl){

		$this->filtroStrategy = new Datagrid_Filtro_Default($this);
		$this->ordenacaoStrategy = new Datagrid_Ordenacao_Default($this);
		$this->itensControlStrategy = new Datagrid_ItensControl_Default($this);

		if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->Start("Datagrid::AjustaControle");
		$itens_por_pagina = @$_REQUEST['itens_por_pagina'];
		$itens_por_pagina = ($itens_por_pagina) ? $itens_por_pagina : $ctrl->ItensPorPagina();
		
		$this->grid_campos 			= $ctrl->GridCampos();
		$this->chave_primaria 		= $ctrl->ChavePrimaria();
		$this->acoes_permitidas 	= $ctrl->GridGetAcoes();
		$this->grid_filtros			= $ctrl->GridFiltros();
		$this->grid_pagina			= $ctrl->GridPagina();
		$this->extensao_paginacao 	= $ctrl->GridExtensaoPaginacao();
		$this->itens_por_pagina		= ($itens_por_pagina) ? $itens_por_pagina : $this->itens_por_pagina;
		$this->ctrl					= $ctrl;
		$this->ordenacao			= $ctrl->Ordenacao();

		if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->End("Datagrid::AjustaControle");
	}

	/**
	 * Gera a barra de paginação
	 * 
	 * @param integer 
	 * @param integer 
	 * @param integer 
	 * @param integer 
	 * 
	 * @return string
	 */
	public function GerarPaginacao($atual, $em_volta, $primeira, $ultima){
		if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->Start("Datagrid::GerarPaginacao");

		$anterior = ($atual > 1) ? $atual - 1 : 1;
		$proxima = ($atual < $ultima) ? $atual + 1 : $ultima;
		$app_folder = (APP_FOLDER) ? "/" . APP_FOLDER : "";
		$nome_pagina = strtolower($this->ctrl->GetSistema()->GetPaginaAtual()->GetNome());
		$lista = '<ul id="paginacao">
					<li><a href="javascript:void(0);" onclick="Sofia.MudaPagina(' . $primeira . ', \'' . $nome_pagina . '\');"><img src="' . $app_folder . '/shell/img/primeira.png" border="0"></a></li>
					<li><a href="javascript:void(0);" onclick="Sofia.MudaPagina(' . $anterior . ', \'' . $nome_pagina . '\')"><img src="' . $app_folder . '/shell/img/anterior.png" border="0"></a></li>';

		foreach($em_volta as $pag){
			if($pag == $atual){
				$lista .= '<li><a href="javascript:void(0);" onclick="Sofia.MudaPagina(' . $pag . ', \'' . $nome_pagina . '\')"><b>' . $pag . '</b></a></li>';
			}else{
				$lista .= '<li><a href="javascript:void(0);" onclick="Sofia.MudaPagina(' . $pag . ', \'' . $nome_pagina . '\')">' . $pag . '</a></li>';
			}
		}

		$lista .= '		<li><a href="javascript:void(0);" onclick="Sofia.MudaPagina(' . $proxima . ', \'' . $nome_pagina . '\')"><img src="' . $app_folder . '/shell/img/proxima.png" border="0"></a></li>
				   		<li><a href="javascript:void(0);" onclick="Sofia.MudaPagina(' . $ultima . ', \'' . $nome_pagina . '\');"><img src="' . $app_folder . '/shell/img/ultima.png" border="0"></a></li>
				   </ul>';

		if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->End("Datagrid::GerarPaginacao");
		return $lista;
	}

	/**
	 * Gera Datagrid da página
	 * 
	 * @return string
	 */
	public function GerarDataGrid(){
		if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->Start("Datagrid::GerarDataGrid");
		
		$nome_pagina = ucfirst($this->ctrl->GetSistema()->GetPaginaAtual()->GetNome());
		$nome_pagina_lowcase = strtolower($this->ctrl->GetSistema()->GetPaginaAtual()->GetNome());

		//---------------- Criando a query
		if($this->ctrl->GetGridQuery()){
			$query = $this->ctrl->GetGridQuery();
		}else{
			$query = $this->ctrl->getDao()->CriaQuery();
			$query->from("{$this->ctrl->NomeModelo()} a");
		}
		
		//---------------- Configurando os possíveis filtros
		$this->filtroStrategy->aplicaFiltro($this->grid_filtros,$query);

		//---------------- Configurando a Ordenação
		$ordem_padrao = $this->ordenacao;
		$this->ordenacaoStrategy->aplicarOrdenacao($ordem_padrao, $query);

		$pagina_corrente = ($_REQUEST['corrente']) ? $_REQUEST['corrente'] : 1;

		//---------------- Criando a paginaçao
		$pager = new Doctrine_Pager($query, $pagina_corrente, $this->itens_por_pagina);
		$result = $pager->execute();

		if(sizeof($result) == 0){
			return "Nenhum registro encontrado";
		}

		$total_paginas = $pager->getLastPage();
		$paginacao = $pager->getRange('Sliding',array('chunk' => $this->extensao_paginacao));
		$total_registros = $pager->getNumResults();
		$em_torno = $paginacao->rangeAroundPage();
		$primeira_pagina = $pager->getFirstPage();
		$ultima_pagina	= $pager->getLastPage();
		$html_paginacao = $this->GerarPaginacao($pagina_corrente, $em_torno, $primeira_pagina, $ultima_pagina);

		//---------------- Gerando cabeçalho do datagrid
		$campos = $this->grid_campos;
		$cabecalho = '<tr class="table-header">';
		$lista_campos = array();
		$total_campos = sizeof($campos);

		$total_tabela = (sizeof($this->acoes_permitidas) > 0) ? $total_campos : ($total_campos - 1);

		foreach($campos as $campo){
			if($campo->GetNome()){
				$cabecalho .= "<td><a href='javascript:void(0);' id='{$campo->GetNome()}' class='iten-title' />{$campo->GetLabel()}</a></td>";
			}else{
				$cabecalho .= "<td>{$campo->GetLabel()}</td>";
			}
		}

		$cabecalho .=  (sizeof($this->acoes_permitidas) > 0) ? "<td>Ação</td></tr>" : '';

		//---------------- Montando o select para exibição de itens por pagina
		if(sizeof($result) > 0){
			$itens_controle = $this->itensControlStrategy->aplicarItensControl($total_registros, $nome_pagina_lowcase, $this->itens_por_pagina);

			//---------------- montando o cabeçalho
			$tabela = '<table width="100%" cellpadding="2" cellspacing="0" id="table-list">';
			$html_pag_final = '<tr class="paginacao">
									<td colspan="' . $total_tabela . '">
										' . $html_paginacao . '
									</td>
									<td>
										' . $itens_controle . '
									</td>
								</tr>';
			$tabela .= $html_pag_final;
			$tabela .= $cabecalho;

			//---------------- Tabelando os dados
			/*
			 * Verifico aqui os arrays dos campos enviados, quais são as opções enviadas e tratando de acordo com o necessário
			 */
			$trigger = 0;
			foreach($result as $model){
				if($trigger){
					$tr_class = "tr-2";
					$trigger = 0;
				}else{
					$tr_class = "tr-1";
					$trigger = 1;
				}

				$tabela .= "<tr class='{$tr_class}'>";
				foreach($campos as $campo){
					try {
						if(!$campo instanceof Datagrid_Campo) throw new Exception('O campo informado não é um Datagrid_Campo.');

						$tipo = $campo->GetParametros("tipo");
						$render = Datagrid_RendererFactory::createRenderizador($tipo);
						$rendered = $render->render($campo, $model);

						$tabela .= "<td>" . $rendered . "</td>";
					}catch (Exception $e) {
					    die("Erro: {$e->getMessage()}\n");
					}
				}

			//---------------- Configurando a célular de ações conforme configuração do usuário
				if(sizeof($this->acoes_permitidas) > 0){
					$tabela .= "<td>";
					foreach($this->acoes_permitidas as $acao){
						try {
							if(!$acao instanceof Datagrid_Campo) throw new Exception('A ação informada não é um Datagrid_Campo.');
							$tipo = $acao->GetParametros("tipo");
							if(!$tipo) throw new Exception('É necessário espeficicar um tipo para a ação');
	
							$render = Datagrid_RendererFactory::createRenderizador($tipo);
							$rendered = $render->render($acao, $model);
							
							$tabela .= $rendered;
						}catch (Exception $e){
							die("Erro: {$e->getMessage()}");
						}
					}
				
					$tabela .= '</td>';
				}

				$tabela .= "</tr>";
			}

			$tabela .= $html_pag_final;
			$tabela .= '</table>';
			$lista_tabela = $tabela;

			if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->End("Datagrid::GerarDataGrid");
			return $lista_tabela;

		}else{
			if(Sistema::GetInstancia()->GetMedidor()) Velocimetro::GetInstancia()->End("Datagrid::GerarDataGrid");
			return false;
		}
	}
}